package com.laputark.petTalent;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.List;
import java.util.Properties;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

import com.sun.xml.internal.ws.util.ByteArrayBuffer;

import weibo4j.Status;
import weibo4j.User;
import weibo4j.Weibo;
import weibo4j.WeiboException;
import weibo4j.http.ImageItem;

public class Publisher {

	private Weibo weibo;
	private String publisherName;
	private SessionFactory sessionFactory;
	private String accessToken;
	private String accessTokenSecret;
	private String publisherId;
	
	@SuppressWarnings("deprecation")
	public Publisher() {
		loadConfiguration();
		System.setProperty("weibo4j.oauth.consumerKey", Weibo.CONSUMER_KEY);
    	System.setProperty("weibo4j.oauth.consumerSecret", Weibo.CONSUMER_SECRET);
    	weibo = new Weibo();
		weibo.setToken(this.accessToken, this.accessTokenSecret);
		Configuration config = new Configuration().configure();
		sessionFactory = config.buildSessionFactory();
	}
	
	private void loadConfiguration() {
		InputStream is = this.getClass().getResourceAsStream("/config.properties");
		Properties properties = new Properties();
		try {
			properties.load(is);
			this.accessToken = properties.getProperty("accessToken");
			this.accessTokenSecret = properties.getProperty("accessTokenSecret");
			this.publisherId = properties.getProperty("publisherId");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private Status getRootStatus(Status status) {
		Status retweeted_status = status.getRetweeted_status();
		return retweeted_status != null ? getRootStatus(retweeted_status) : status;
	}
	
	private ImageItem getStatusImage(Status status) throws IOException, WeiboException {
		String imageUrl = status.getOriginal_pic();
		if (imageUrl == null || imageUrl.isEmpty())
			return null;
		URL url = new URL(imageUrl);
		InputStream is = url.openStream();
		byte[] buffer = readImageBytes(is);
		is.close();
		return new ImageItem(buffer);
	}
	
	private byte[] readImageBytes(InputStream is) throws IOException {
		ByteArrayBuffer ba = new ByteArrayBuffer();
		byte[] buffer = new byte[1024];
		int length;
		while ((length = is.read(buffer)) != -1) {
			ba.write(buffer, 0, length);
		}
		return ba.getRawData();
	}

	private void uploadModifiedStatus(Status status) throws IOException, WeiboException {
		User user = status.getUser();
		if (this.isValidCreator(user)) {
			Status rs = this.getRootStatus(status);
			ImageItem ii = this.getStatusImage(rs);
			if (ii == null) {
				System.out.println("no image: " + rs.getText());
			} else {
				String text = rs.getText();
				text = this.modifyStatusText(text);
				System.out.println(text);
				weibo.uploadStatus(text, ii);
			}
		}
	}

	private String modifyStatusText(String text) {
		text = text.replaceAll("#.*#", "");
		text = text.replaceAll("\\s*关注\\s*@\\S*", "关注@" + this.getPublisherName());
		return text;
	}

	private boolean isValidCreator(User creator) {
		String creatorId = String.valueOf(creator.getId());
		Session s = this.sessionFactory.openSession();
		ValidEditor editor = (ValidEditor) s.get(ValidEditor.class, creatorId);
		s.close();
		return editor != null;
	}
	
	private void run() {
		try {
			fetchPublisherName();
			List<Status> mentions = this.weibo.getMentions();
			for (Status mention : mentions) {
				if (isProcessed(mention))
					break;
				uploadModifiedStatus(mention);
				setProcessed(mention);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private boolean isProcessed(Status mention) {
		String id = String.valueOf(mention.getId());
		Session s = this.sessionFactory.openSession();
		ProcessedStatus ps = (ProcessedStatus) s.get(ProcessedStatus.class, id);
		s.close();
		return ps != null;
	}
	
	private void setProcessed(Status status) {
		String id = String.valueOf(status.getId());
		ProcessedStatus ps = new ProcessedStatus(id);
		Session s = this.sessionFactory.openSession();
		s.getTransaction().begin();
		s.saveOrUpdate(ps);
		s.getTransaction().commit();
		s.close();
	}

	private void fetchPublisherName() throws WeiboException {
		User publisher = this.weibo.showUser(this.publisherId);
		String name = publisher.getName();
		System.out.println("publisher: " + name);
		this.setPublisherName(name);
	}
	
	public String getPublisherName() {
		return publisherName;
	}

	public void setPublisherName(String publisherName) {
		this.publisherName = publisherName;
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Publisher pb = new Publisher();
		pb.run();
	}
	
}
